// Copyright (c) 2022 NetEase, Inc. All rights reserved.
// Use of this source code is governed by a MIT license that can be
// found in the LICENSE file.

import 'package:hawk/hawk.dart';
import 'package:nim_core/nim_core.dart';

import 'method_name_value.dart';
import '../main_test.dart';

class HandleSignallingCase extends HandleBaseCase {
  HandleSignallingCase();

  @override
  Future<ResultBean?> handle(event) async {
    super.handle(event);
    var handled = false;
    var isCallback = false;
    var result;
    if (className != 'AvSignallingService') {
      return null;
    }
    switch (methodName) {
      case onlineNotification:
        isCallback = true;
        subsriptions.add(NimCore.instance.avSignallingService.onlineNotification
            .listen((event) {
          print('AvSignallingService#onlineNotification ${event.toJson()}');
          IntegratedManager.instance.report(
              'onlineNotification', ResultBean(code: 0, data: event.toJson()));
        }));
        break;
      case offlineNotification:
        isCallback = true;
        subsriptions.add(NimCore
            .instance.avSignallingService.offlineNotification
            .listen((event) {
          print('AvSignallingService#offlineNotification ');
          IntegratedManager.instance.report('offlineNotification',
              ResultBean(code: 0, data: event.map((e) => e.toJson()).toList()));
        }));
        break;
      case onMemberUpdateNotification:
        isCallback = true;
        subsriptions.add(NimCore
            .instance.avSignallingService.onMemberUpdateNotification
            .listen((event) {
          print('AvSignallingService#onMemberUpdateNotification ');
          IntegratedManager.instance.report('onMemberUpdateNotification',
              ResultBean(code: 0, data: event.toJson()));
        }));
        break;
      case syncChannelListNotification:
        isCallback = true;
        subsriptions.add(NimCore
            .instance.avSignallingService.syncChannelListNotification
            .listen((event) {
          print('AvSignallingService#syncChannelListNotification ');
          IntegratedManager.instance.report('syncChannelListNotification',
              ResultBean(code: 0, data: event.map((e) => e.toJson()).toList()));
        }));
        break;
      case otherClientInviteAckNotification:
        isCallback = true;
        subsriptions.add(NimCore
            .instance.avSignallingService.otherClientInviteAckNotification
            .listen((event) {
          print('AvSignallingService#otherClientInviteAckNotification ');
          IntegratedManager.instance.report('otherClientInviteAckNotification',
              ResultBean(code: 0, data: event.toJson()));
        }));
        break;
      case createChannel:
        {
          var map = params![0];
          print("create channel with param ${map.toString()}");
          var type = getChannelTypeFromString(map['type']);
          final ret = await NimCore.instance.avSignallingService.createChannel(
              type: type,
              channelName: map['channelName'],
              channelExt: map['channelExt']);
          result = ret;
          handled = true;
          break;
        }
      case joinChannel:
        {
          var map = params![0];
          print("join channel with param ${map.toString()}");
          final ret = await NimCore.instance.avSignallingService.joinChannel(
              channelId: map['channelId'],
              selfUid: map['selfUid'],
              customInfo: map['customInfo'],
              offlineEnabled: map['offlineEnabled']);
          result = ret;
          handled = true;
          break;
        }
      case invite:
        {
          var map = params![0]['inviteParam'];
          print("invite with param ${map.toString()}");
          final ret = await NimCore.instance.avSignallingService
              .invite(InviteParam.fromJson(map.cast<String, dynamic>()));
          result = ret;
          handled = true;
          break;
        }
      case closeChannel:
        {
          var map = params![0];
          print("close Channel with param ${map.toString()}");
          final ret = await NimCore.instance.avSignallingService.closeChannel(
              channelId: map['channelId'],
              offlineEnabled: map['offlineEnabled'],
              customInfo: map['customInfo']);
          result = ret;
          handled = true;
          break;
        }
      case leaveChannel:
        {
          var map = params![0];
          print("leave Channel with param ${map.toString()}");
          final ret = await NimCore.instance.avSignallingService.leaveChannel(
              channelId: map['channelId'],
              offlineEnabled: map['offlineEnabled'],
              customInfo: map['customInfo']);
          result = ret;
          handled = true;
          break;
        }
      case cancelInvite:
        {
          var map = params![0]['inviteParam'];
          print("cancel invite with param ${map.toString()}");
          final ret = await NimCore.instance.avSignallingService
              .cancelInvite(InviteParam.fromJson(map.cast<String, dynamic>()));
          result = ret;
          handled = true;
          break;
        }
      case rejectInvite:
        {
          var map = params![0]['inviteParam'];
          print("reject invite with param ${map.toString()}");
          final ret = await NimCore.instance.avSignallingService
              .rejectInvite(InviteParam.fromJson(map.cast<String, dynamic>()));
          result = ret;
          handled = true;
          break;
        }
      case acceptInvite:
        {
          var map = params![0]['inviteParam'];
          print("accept invite with param ${map.toString()}");
          final ret = await NimCore.instance.avSignallingService
              .acceptInvite(InviteParam.fromJson(map.cast<String, dynamic>()));
          result = ret;
          handled = true;
          break;
        }
      case sendControl:
        {
          var map = params![0];
          print("send control with param ${map.toString()}");
          final ret = await NimCore.instance.avSignallingService.sendControl(
              channelId: map['channelId'],
              accountId: map['accountId'],
              customInfo: map['customInfo']);
          result = ret;
          handled = true;
          break;
        }
      case call:
        {
          var map = params![0]['callParam'];
          print("call with param ${map.toString()}");
          final ret = await NimCore.instance.avSignallingService
              .call(CallParam.fromJson(map.cast<String, dynamic>()));
          result = ret;
          handled = true;
          break;
        }
      case queryChannelInfo:
        {
          var map = params![0];
          print("queryChannelInfo with param ${map.toString()}");
          final ret = await NimCore.instance.avSignallingService
              .queryChannelInfo(map['channelName']);
          result = ret;
          handled = true;
          break;
        }
    }
    if (handled) {
      print('AvSignallingService#$methodName result: ${result.code}');
      handleCaseResult = ResultBean(
        code: result.code,
        data: result.data?.toJson(),
        message: result.errorDetails,
      );
    }
    if (isCallback) {
      handleCaseResult = ResultBean.success(data: null);
    }
    return handleCaseResult;
  }

  ChannelType getChannelTypeFromString(String type) {
    switch (type) {
      case 'audio':
        return ChannelType.audio;
      case 'video':
        return ChannelType.video;
      default:
        return ChannelType.custom;
    }
  }
}
